#include "HandBrkModel.h"
#include "Common/Information.h"
#include "Common/DataStructureMacro.h"
#include "HandbrkUniteView.h"
#include "audio_service_api.h"
#include "ssas_api.h"
#define LOG_TAG "HMI"
#include "log_api.h"

#define HANDBRK_AUDIO_ID AUDIO_2

typedef enum
{
    ALWAYS_OFF,
    ALWAYS_ON,
    HANDBRK_POPUP,
} MachineState;

typedef enum
{
    IDLE,
    ALARM,
} ChildMachineState;

static MachineState      currentStatus;      //state
static ChildMachineState childCurrentStatus; 
static Option_U8         showFlag;           //ctrl ui 

static MachineState getNewState()
{
    MachineState newStatus = ALWAYS_OFF;
    int msgState = COM_MSG_INIT;
    Std_ReturnType comRet = E_NOT_OK;
    do
    {
        if(!isFinishSelfTest(SELF_TEST_3S)) // 3s
        {
            newStatus = ALWAYS_ON;
            break;
        }

        msgState = get_message_state(COM_IC_HEV_GENERAL_STATUS_1);
        if(COM_MSG_INIT == msgState || COM_MSG_TIMEOUT == msgState)
        {
            newStatus = ALWAYS_OFF;
            break;
        }

        int rawData = 0;        
        if (E_OK != Com_ReceiveSignal(COM_SID_HandBrkSts, &rawData))
        {
            newStatus = ALWAYS_OFF;
            break;
        }

        if(rawData == OFF)
        {
            newStatus = ALWAYS_OFF;
        }
        else
        {
            newStatus = HANDBRK_POPUP;
        }
        break;

    } while (false);

    return newStatus; 
}

static void handleEntryOnAndPopup()
{
    float speed = 0.0f;
    getShowSpeed(&speed);
    if((int)speed > 5)
    {
        childCurrentStatus = ALARM;
        play_sound_request(HANDBRK_AUDIO_ID, 500, 500, 0);
    }
    else
    {
        childCurrentStatus = IDLE;
    }
}

static void handleLeaveOnAndPopup()
{
    if(ALARM == childCurrentStatus)
    {
        stop_sound_request(HANDBRK_AUDIO_ID);
    }
    else
    {

    }
    childCurrentStatus = IDLE;
}

static void handlStateTransition(MachineState newStatus)
{
    if(currentStatus != newStatus)
    {
        switch (currentStatus)
        {
            case HANDBRK_POPUP:
            {
                handleLeaveOnAndPopup();
                break;
            }

            case ALWAYS_OFF:
            case ALWAYS_ON:
                /* ignore */
                break;
            
            default:
                LOG_E("Handbrk exit unknow status : %d\n", currentStatus);
                break;
        }

        currentStatus = newStatus;

        switch (currentStatus)
        {
            case HANDBRK_POPUP:
                handleEntryOnAndPopup();
                break;

            case ALWAYS_OFF:
            case ALWAYS_ON:
                /* ignore */
                break;
            
            default:
                LOG_E("Handbrk entry unknow status : %d\n", currentStatus);
                break;
        }
    }
    
}

static void handleExecuteOnAndPopup()
{
    float speed = 0.0f;
    getShowSpeed(&speed);
    if(childCurrentStatus == ALARM)
    {
        if(((int)speed) == 0)
        {
            childCurrentStatus = IDLE;
            stop_sound_request(HANDBRK_AUDIO_ID);
        }
    }
    else
    {
        if(speed >= 5.0f)
        {
            childCurrentStatus = ALARM;
            play_sound_request(HANDBRK_AUDIO_ID, 500, 500, 0);
        }
    }
}

static void postprocess()
{
    switch (currentStatus)
    {
        case HANDBRK_POPUP:
        {
            handleExecuteOnAndPopup();
            setOptionValue_U8(&showFlag, true);
            break;
        }

        case ALWAYS_OFF:
            setOptionValue_U8(&showFlag, false);
            break;

        case ALWAYS_ON:
            setOptionValue_U8(&showFlag, true);
            break;
    
        default:
            break;
    }
}

static void run()
{
    if(handbrk_unite_visble_mask)
    {
        MachineState newStatus = getNewState();
        handlStateTransition(newStatus);
        postprocess();
    }
}

static void init()
{
    currentStatus = ALWAYS_OFF;
    childCurrentStatus = IDLE;
    showFlag.update_ = false;
    showFlag.value_ = 0;
}

static void release()
{

}

HandBrkModel g_HandBrkModelInstance = {
    {
        init,
        run,
        release,
        MIN_PERIOD,
    },
};

Option_U8 getHandbrkShowFlag()
{
    return showFlag;
}

